/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package controller

import (
	"did-service/auth"
	"did-service/bean/param"
	"did-service/common/constant"
	"did-service/common/crypto/gm"
	"did-service/common/http"

	"github.com/emicklei/go-restful"
)

func (dc *DidController) DidOperation(req *restful.Request, resp *restful.Response) {
	var documentParam param.DocumentParam
	if err := req.ReadEntity(&documentParam); err != nil {
		log.Errorf("parameter types do not match error: %s", err)
		http.Failed(resp, "参数格式不正确")
		return
	}
	walletId := auth.GetCurrentWalletId(req)
	if documentParam.Operation == "create" {
		if err := dc.srv.InsertDocument(walletId, &documentParam); err != nil {
			log.Errorf("create did document error: %v", err)
			http.Failed(resp, "创建失败")
			return
		}
		http.Ok(resp, "创建成功")

	} else if documentParam.Operation == "delete" {
		if err := dc.srv.DeleteDocument(&documentParam); err != nil {
			log.Errorf("delete did document error: %v", err)
			http.Failed(resp, "删除失败")
			return
		}
		http.Ok(resp, "删除成功")
	}

}

func (dc *DidController) SignByKey(req *restful.Request, resp *restful.Response) {
	var signParam param.DidSignParam
	if err := req.ReadEntity(&signParam); err != nil {
		log.Errorf("parameter types do not match error: %s", err)
		http.Failed(resp, "参数格式不正确")
		return
	}
	if signParam.KeyId == "" {
		log.Errorf("key id is empty")
		http.Failed(resp, "keyId不能为空")
	}
	if signParam.Payload == "" {
		log.Errorf("payload is empty")
		http.Failed(resp, "payload不能为空")
	}
	keyInfo, err := dc.srv.GetKeyInfo(signParam.KeyId)
	if err != nil {
		log.Errorf("get key error: %s", err)
		http.Failed(resp, "获取签名私钥失败")
		return
	}
	if keyInfo == nil {
		log.Errorf("key id is not exist")
		http.Failed(resp, "秘钥不存在")
		return
	}
	walletId := auth.GetCurrentWalletId(req)
	didDocument, err := dc.srv.GetWalletByDid(keyInfo.Did)
	if didDocument.WalletId != walletId {
		log.Warning("have no auth")
		http.Failed(resp, "无权限使用")
		return
	}

	signature := ""
	if signParam.Format == constant.EncodeFormatHex {
		signature = gm.Sign(keyInfo.PrvKey, []byte(signParam.Payload))
	} else {
		signature = gm.SignWithBase64(keyInfo.PrvKey, []byte(signParam.Payload))
	}

	http.OkWithData(resp, "签名成功", struct {
		Signature string `json:"signature"`
	}{Signature: signature})
}

func (dc *DidController) VerifyByKey(req *restful.Request, resp *restful.Response) {
	var verifyParam param.DidVerifyParam
	if err := req.ReadEntity(&verifyParam); err != nil {
		log.Errorf("parameter types do not match error: %s", err)
		http.Failed(resp, "参数格式不正确")
		return
	}
	if verifyParam.KeyId == "" && verifyParam.PubKey == "" {
		log.Errorf("key id and pubkey is empty")
		http.Failed(resp, "keyId和pubKey不能同时为空")
	}
	if verifyParam.Payload == "" {
		log.Errorf("payload is empty")
		http.Failed(resp, "payload不能为空")
	}
	if verifyParam.Signature == "" {
		log.Errorf("signature is empty")
		http.Failed(resp, "signature不能为空")
	}

	pubKey := verifyParam.PubKey
	if pubKey == "" {
		keyInfo, err := dc.srv.GetKeyInfo(verifyParam.KeyId)
		if err != nil {
			log.Errorf("get key error: %s", err)
			http.Failed(resp, "获取公钥失败")
			return
		}
		if keyInfo == nil {
			log.Errorf("key id is not exist")
			http.Failed(resp, "公钥不存在")
			return
		}
		pubKey = keyInfo.PubKey
	}

	result := false
	if verifyParam.Format == constant.EncodeFormatHex {
		result = gm.Verify(pubKey, []byte(verifyParam.Payload), verifyParam.Signature)
	} else {
		result = gm.VerifyWithBase64(pubKey, []byte(verifyParam.Payload), verifyParam.Signature)
	}
	http.OkWithData(resp, "验签完成", struct {
		Result bool `json:"result"`
	}{result})
}
